﻿<DemoPageSectionComponent Id="DataGrid-Editing-CascadingEditors" ShowHorizontalScrollBar="true">
    @implements IDisposable
    @inject NwindDataService NwindDataService
    @inject WorldcitiesDataService WorldcitiesDataService

    @if(Data == null) {
        <p><em>Loading...</em></p>
    } else {
        <DxDataGrid Data="@Data"
                    @ref="@grid"
                    PageSize="8"
                    InitNewRow="@OnInitNewRowAsync"
                    RowRemovingAsync="@((dataItem) => OnRowRemoving(dataItem))"
                    RowInsertingAsync="@((newValues) => OnRowInserting(newValues))"
                    RowUpdatingAsync="@((dataItem, newValues) => OnRowUpdating(dataItem, newValues))">
            <DxDataGridCommandColumn Width="150px"></DxDataGridCommandColumn>
            <DxDataGridColumn Field="@nameof(Supplier.CompanyName)" />
            <DxDataGridColumn Field="@nameof(Supplier.ContactName)" />
            <DxDataGridColumn Field="@nameof(Supplier.ContactTitle)" />
            <DxDataGridColumn Field="@nameof(Supplier.Phone)" />
            <DxDataGridComboBoxColumn Field="@nameof(Supplier.Country)" Data="@Countries">
                <EditTemplate>
                    @{
                        var editingContext = (CellEditContext)context;
                        var country = (string)editingContext.GetEditorValue(nameof(Supplier.Country));
                    }
                    <DxComboBox Data="@Countries"
                                NullText="Select Country..."
                                TextFieldName="@nameof(Country.CountryName)"
                                ValueFieldName="@nameof(Country.CountryName)"
                                Value="@country"
                                ValueChanged="@(EventCallback.Factory.Create(this, (string newCellValue) => {
                                                    editingContext.OnChanged(newCellValue);
                                                    editingContext.OnChanged(nameof(Supplier.City), null);
                                                    }))">
                    </DxComboBox>
                </EditTemplate>
            </DxDataGridComboBoxColumn>
            <DxDataGridColumn Field="@nameof(Supplier.City)">
                <EditTemplate>
                    @{
                        var editingContext = (CellEditContext)context;

                        var country = (string)editingContext.GetEditorValue(nameof(Supplier.Country));
                        var city = ((string)(editingContext.GetEditorValue(nameof(Supplier.City))));
                        var countryId = Countries.Where(c => c.CountryName == country).FirstOrDefault()?.CountryId;
                        var cities = Cities.Where(x => x.CountryId == countryId);
                    }
                    <DxComboBox Data="@cities"
                                NullText="Select City..."
                                Text="@city"
                                TextFieldName="@nameof(City.CityName)"
                                ValueFieldName="@nameof(City.CityName)"
                                ValueChanged="@(EventCallback.Factory.Create(this, (string newCellValue) => editingContext.OnChanged(newCellValue)))">
                    </DxComboBox>
                </EditTemplate>
            </DxDataGridColumn>
        </DxDataGrid>
    }

    @code {

        readonly TaskCompletionSource<Supplier> firstSupplierTcs = new (TaskCreationOptions.RunContinuationsAsynchronously);
        IEnumerable<Supplier> Data;
        IEnumerable<Country> Countries;
        IEnumerable<City> Cities;
        DxDataGrid<Supplier> grid;

        protected override async Task OnInitializedAsync() {
            var (dataTask, countriesTask, citiesTask) = (NwindDataService.GetSuppliersEditableAsync(), 
                        WorldcitiesDataService.GetCountriesAsync(),
                        WorldcitiesDataService.GetCitiesAsync());
            (Data, Countries, Cities) = (await dataTask, await countriesTask, await citiesTask);
            firstSupplierTcs.TrySetResult(Data.FirstOrDefault());
        }
        protected override async Task OnAfterRenderAsync(bool firstRender) {
            if(firstRender) {
                var editableSupplier = await firstSupplierTcs.Task;
                await grid.StartRowEdit(editableSupplier);
            }
        }
        async Task OnRowUpdating(Supplier supplier, IDictionary<string, object> newValues) {
            await NwindDataService.UpdateSupplierAsync(supplier, newValues);
            await UpdateDataAsync();
        }
        async Task OnRowRemoving(Supplier supplier) {
            await NwindDataService.RemoveSupplierAsync(supplier);
            await UpdateDataAsync();
        }
        async Task OnRowInserting(IDictionary<string, object> newValues) {
            await NwindDataService.InsertSupplierAsync(newValues);
            await UpdateDataAsync();
        }
        Task OnInitNewRowAsync(Dictionary<string, object> values) {
            values.Add(nameof(Supplier.CompanyName), "DevExpress");
            values.Add(nameof(Supplier.ContactName), "John Doe");
            return Task.CompletedTask;
        }
        async Task UpdateDataAsync() {
            Data = await NwindDataService.GetSuppliersEditableAsync();
            StateHasChanged();
        }
        public void Dispose() {
            firstSupplierTcs.TrySetCanceled();
        }
    }
</DemoPageSectionComponent>
